高可用的定义
高可用(High Availability)是指系统在面临各种故障(硬件故障、软件缺陷、网络中断)时,仍能持续提供服务的能力。通常用"几个9"来衡量可用性级别:
| 可用性 | 年停机时间 | 等级 |
|---|---|---|
| 99% | 3.65天 | 基本可用 |
| 99.9% | 8.76小时 | 高可用 |
| 99.99% | 52.56分钟 | 自动化恢复 |
| 99.999% | 5.26分钟 | 极高可用 |
从99%提升到99.9%相对容易,但从99.99%提升到99.999%的成本是指数级增长的。
本地高可用架构
冗余部署
本地高可用的核心思想是冗余——关键组件部署多个实例,一个故障时另一个自动接管。
应用层冗余:多个应用服务实例 + 负载均衡。Nginx配置健康检查,自动剔除故障节点。
数据库冗余:主从复制。主库负责写操作,从库负责读操作。主库故障时将从库提升为主库。
缓存冗余:Redis Sentinel或Redis Cluster,主节点故障时自动故障转移。
故障检测与自动恢复
| 机制 | 说明 |
|---|---|
| 心跳检测 | 定期向服务发送心跳包,无响应则标记为不可用 |
| 健康检查 | 负载均衡器定期检查后端服务健康状态 |
| 自动重启 | 进程崩溃时自动重启(PM2、Supervisor) |
| 熔断器 | 连续失败达到阈值后自动熔断,避免故障扩散 |
逻辑保护
逻辑保护是指在代码层面预防故障的发生和扩散。
超时保护
所有外部调用必须设置超时时间。没有超时的请求会一直占用资源,最终拖垮整个系统。
// 超时控制示例
async function fetchWithTimeout(url: string, timeout = 5000) {
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), timeout)
try {
const response = await fetch(url, { signal: controller.signal })
return response.json()
} finally {
clearTimeout(timer)
}
}
typescript
重试机制
对于临时性故障(网络抖动、服务短暂不可用),合理的重试可以提高成功率。但重试需要设置上限和退避策略(指数退避),避免雪崩。
熔断降级
当某个服务的错误率超过阈值时,熔断器打开,后续请求直接返回降级结果而不是继续调用故障服务。这防止了故障的级联扩散。
限流
限制单位时间内的请求数量,防止突发流量压垮系统。常见的限流算法包括:
- 计数器限流
- 滑动窗口限流
- 令牌桶算法
- 漏桶算法
数据一致性保护
分布式系统中,数据复制存在延迟。需要通过策略保证最终一致性:
- 写操作在主库执行后,同步等待至少一个从库确认
- 读取时根据业务需求选择读主库还是读从库
- 通过消息队列保证最终一致性
↑